package com.pig4cloud.pigx.contract.executer.position;

import com.pig4cloud.pigx.common.customize.exception.MqAckException;
import com.pig4cloud.pigx.common.customize.mysql.utils.MysqlUtil;
import com.pig4cloud.pigx.contract.constant.ContractMqConstants;
import com.pig4cloud.pigx.contract.dto.AppContractMultipleChangeDTO;
import com.pig4cloud.pigx.contract.dto.ContractPositionMarginAppendDTO;
import com.pig4cloud.pigx.contract.executer.position.margin_appender.PositionMarginAppender;
import com.pig4cloud.pigx.contract.executer.position.migrator.PositionMigrator;
import com.pig4cloud.pigx.contract.executer.position.multiple_changer.PositionMultipleChangerManager;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 仓位执行器
 *
 * @since 2022/8/28 20:58
 */
@Slf4j
@Component
@AllArgsConstructor
public class PositionExecutor {

    private final PositionMultipleChangerManager positionMultipleChangerManager;
    private final PositionMigrator positionMigrator;
    private final PositionMarginAppender positionMarginAppender;

    private final MysqlUtil mysqlUtil;

    /**
     * 调整杠杆
     *
     * @param dto dto
     * @since 2022/9/9 10:37
     */
    public void multipleChange(AppContractMultipleChangeDTO dto) {
        log.info("{} 开始调整杠杆。dto：{}", this.getClass().getSimpleName(), dto);
        positionMultipleChangerManager.change(dto);
    }

    /**
     * 监听 contract.position.migrate 队列，历史仓位迁移
     *
     * @param positionIdList 仓位idList
     * @since 2022/9/20 16:20
     */
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = ContractMqConstants.QUEUE_FANOUT_CONTRACT_POSITION_MIGRATE),
                    exchange = @Exchange(value = ContractMqConstants.EXCHANGE_FANOUT_CONTRACT_POSITION_MIGRATE, type = ExchangeTypes.FANOUT)
            )})
    public void migrate(List<Long> positionIdList) {
        // 开启本地事务
        mysqlUtil.startLocalTx();
        try {
            // 迁移
            positionMigrator.migrator(positionIdList);
            // 提交本地事务
            mysqlUtil.commitLocalTx();
        } catch (Throwable e) {
            // 回滚本地事务
            mysqlUtil.rollbackLocalTx();

            if (e instanceof MqAckException) {
                return;
            }
            throw e;
        }
    }

    /**
     * 监听 contract.position.margin.append 队列，开始处理全仓自动追加保证金
     *
     * @param dto dto
     * @since 2022/9/16 16:00
     */
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = ContractMqConstants.QUEUE_FANOUT_CONTRACT_POSITION_MARGIN_APPEND),
                    exchange = @Exchange(value = ContractMqConstants.EXCHANGE_FANOUT_CONTRACT_POSITION_MARGIN_APPEND, type = ExchangeTypes.FANOUT)
            )})
    public void marginAppend(ContractPositionMarginAppendDTO dto) {
        positionMarginAppender.append(dto);
    }
}
